/*************************************************************************
	> File Name: person.h
	> Author: ma6174
	> Mail: ma6174@163.com 
	> Created Time: 2021年12月13日 星期一 20时01分00秒
 ************************************************************************/

#include<iostream>
#include <string>
#include <list>

//抽象类
struct Action;

struct Person
{
	virtual void accept(Action* visitor) = 0;
};

struct Action
{
	virtual void getManConclusion(Person* man) = 0;
	virtual void getWomanConclusion(Person* woman) = 0;
};


//具体“状态”类
struct Success : public Action
{
	virtual void getManConclusion(Person* man)
	{
		std::cout << "男人成功时，背后多半有一个伟大的女人。" << std::endl;
	}

	virtual void getWomanConclusion(Person* woman)
	{
		std::cout << "女人成功时，背后大多有一个不成功的男人。" << std::endl;
	}
};

struct Failing : public Action
{
	virtual void getManConclusion(Person* man)
	{
		std::cout << "男人失败时，闷头喝酒，谁也不用劝。" << std::endl;
	}

	virtual void getWomanConclusion(Person* woman)
	{
		std::cout << "女人失败时，眼泪汪汪，谁也劝不了。" << std::endl;
	}
};

struct Amativeness : public Action
{
	virtual void getManConclusion(Person* man)
	{
		std::cout << "男人恋爱时，不懂都得装懂。" << std::endl;
	}

	virtual void getWomanConclusion(Person* woman)
	{
		std::cout << "女人恋爱时，懂都得装不懂。" << std::endl;
	}
};

struct Marriage : public Action
{
	virtual void getManConclusion(Person* man)
	{
		std::cout << "男人结婚时，成熟稳重的开始。" << std::endl;
	}

	virtual void getWomanConclusion(Person* woman)
	{
		std::cout << "女人结婚时，修成正果。" << std::endl;
	}
};

//人的具体类
struct Man : public Person
{
	virtual void accept(Action* visitor)
	{
		visitor->getManConclusion(this);
	}
};

struct Woman : public Person
{
	virtual void accept(Action* visitor)
	{
		visitor->getWomanConclusion(this);
	}
};

//对象结构
class ObjectStructure
{
public:
	~ObjectStructure()
	{
		for (auto elem : elements)
			delete elem;
	}

	void attach(Person* elem)
	{
		elements.push_back(elem);
	}

	void detach(Person* elem)
	{
		elements.remove(elem);
	}

	void display(Action* visitor)
	{
		for (auto elem : elements)
		{
			elem->accept(visitor);
		}
	}

private:
	std::list<Person*> elements;
};
